<template>
  <DraggableModal
    :width="width"
    ref="modalRef"
    wrapClassName="draggable-modal"
    centered
    :open="open"
    @cancel="onCancel"
    :maskClosable="false"
    :footer="null"
  >
    <div class="modal-content" ref="containerRef">
      <a-spin :spinning="isLoading">
        <a-form ref="formRef" :model="formRows" :rules="formRules">
          <a-table :columns="columns" :dataSource="formRows" bordered sticky :scroll="{ y: 500, x: 500 }" :pagination="false">
            <template #bodyCell="{ column, text, record, index }">
              <template v-if="column.dataIndex === 'field_name'">
                <EllipsisPopover placement="bottom" :content="text" copy>
                  {{ text }}
                </EllipsisPopover>
              </template>
              <template v-else-if="column.dataIndex === 'field_display_name'">
                <a-form-item label="" :name="[index, 'field_display_name']">
                  <a-input v-model:value="record[column.dataIndex]" />
                </a-form-item>
              </template>
              <template v-else-if="column.dataIndex === 'is_check'">
                <a-form-item label="" :name="[index, 'is_check']">
                  <a-switch
                    v-model:checked="record[column.dataIndex]"
                    checked-children="关闭校验"
                    un-checked-children="开启校验"
                    :checked-value="1"
                    :un-checked-value="2"
                  />
                </a-form-item>
              </template>
              <template v-else-if="column.dataIndex === 'is_required'">
                <a-form-item label="" :name="[index, 'is_required']">
                  <a-switch
                    v-model:checked="record[column.dataIndex]"
                    checked-children="非必填"
                    un-checked-children="必填"
                    :checked-value="1"
                    :un-checked-value="2"
                  />
                </a-form-item>
              </template>
              <template v-else-if="column.dataIndex === 'check_method'">
                <a-form-item label="" :name="[index, 'check_method']">
                  <a-select
                    v-model:value="record[column.dataIndex]"
                    :options="[
                      { value: '1', label: '字符串' },
                      { value: '2', label: '整数' },
                      { value: '3', label: '集合值' },
                      { value: '4', label: '手机号' },
                      { value: '5', label: '邮箱' },
                    ]"
                    style="width: 100%"
                  />
                </a-form-item>
              </template>
              <template v-else-if="column.dataIndex === 'check_rules_value'">
                <a-form-item label="" :name="[index, 'check_method']">
                  <a-input v-model:value.trim="record[column.dataIndex]" />
                </a-form-item>
              </template>
              <template v-else-if="column.dataIndex === 'hint_des'">
                <a-form-item label="" :name="[index, 'hint_des']">
                  <a-textarea v-model:value.trim="record[column.dataIndex]" :autosize="{ maxRows: 2, minRows: 2 }" />
                </a-form-item>
              </template>
              <template v-else-if="column.dataIndex === 'remarks'">
                <a-form-item label="" :name="[index, 'remarks']">
                  <a-textarea v-model:value.trim="record[column.dataIndex]" :autosize="{ maxRows: 2, minRows: 2 }" />
                </a-form-item>
              </template>
              <template v-else-if="column.dataIndex === 'action'">
                <a-form-item>
                  <a-button size="small" type="link" @click="onSaveRecord(record)">保存</a-button>
                </a-form-item>
              </template>
            </template>
          </a-table>
        </a-form>
      </a-spin>
    </div>

    <!-- 表单按钮 -->
    <div class="modal-footer">
      <a-form-item class="form-item-buttons">
        <a-flex justify="center" :gap="16">
          <a-button type="primary" htmlType="submit" @click="onFinish">确定</a-button>
          <a-button @click="onCancel">取消</a-button>
        </a-flex>
      </a-form-item>
    </div>
  </DraggableModal>
</template>
<script setup lang="ts">
  import { ref, reactive, computed, watch, watchEffect, type CSSProperties } from 'vue';
  import { useDraggable } from '@vueuse/core';
  import { message } from 'ant-design-vue';
  import { bizApi } from '@/api/biz';
  import EllipsisPopover from '@/components/common/popover/ellipsis-popover.vue'; //自定义的省略文本气泡提示组件，用于处理文本过长时的展示。
  const containerRef = ref();
  const width = 1200;
  const formRef = ref();
  const isLoading = ref(false);

  const title = ref('字段配置');
  const open = ref(false); //控制弹窗显示、隐藏 变量

  const table_config_id = ref(0); //要编辑的数据ID

  /* 弹窗显示 */
  function show(id: number, table_name: string, table_display_name: string) {
    table_config_id.value = id;
    title.value = table_display_name + '(' + table_name + ') 字段配置';
    open.value = true;
  }
  /* 弹窗关闭 */
  function onCancel() {
    open.value = false;
  }

  // 定义单行表单数据类型
  interface FormRow {
    id: number;
    table_config_id: number;
    field_name: string;
    field_display_name: string;
    field_type: string;
    field_length: number;
    is_check: number; // 开启校验
    is_required: number; // 必填/非必填
    check_method: Record<string, any>; // 校验规则
    check_rules_value: string; // 规则值
    hint_des: string; // 校验提示
    remarks: string; // 校验提示
  }
  // 初始化：至少保留一行数据
  const formRows = reactive<FormRow[]>([]);

  const columns = ref([
    { title: '字段名', dataIndex: 'field_name', fixed: 'left', width: 180 },
    { title: '显示名', dataIndex: 'field_display_name', width: 200 },
    { title: '是否校验', dataIndex: 'is_check', width: 120 },
    { title: '是否必填', dataIndex: 'is_required', width: 120 },
    { title: '校验规则', dataIndex: 'check_method', width: 140 },
    { title: '规则值', dataIndex: 'check_rules_value', width: 200 },
    { title: '错误提示', dataIndex: 'hint_des', width: 300 },
    { title: '字段备注', dataIndex: 'remarks', width: 400 },
    { title: '操作', dataIndex: 'action', fixed: 'right', width: 80 },
  ]);

  async function onSaveRecord(record: FormRow) {
    console.log('保存这一行的数据', record);
  }

  /* 获取字段配置列表 参数 */
  const getAction = 'base.manage.fieldconfig.ServiceImpl.list';
  const getParams = computed(() => ({
    table_config_id: table_config_id.value,
  }));

  /* 监听 props.open = true 时，调用 onOpen 方法 并传递 recordId */
  watch(
    () => open.value,
    (val) => {
      if (val === true) {
        console.log('table_config_id=', table_config_id.value);
        getDataInfo(getAction, getParams);
      }
    }
  );

  /* 数据服务请求（访问服务端接口获取数据） */
  async function getDataInfo(action: string, params: Record<string, any>) {
    isLoading.value = true;
    try {
      const result = await bizApi.httpList(action, params.value);
      formRows.length = 0;
      if (Array.isArray(result) && result.length > 0) {
        result.forEach((row) => {
          formRows.push({
            ...row,
            is_check: [1, 2].includes(row.is_check) ? row.is_check : 2,
            is_required: [1, 2].includes(row.is_required) ? row.is_required : 2,
          });
        });
      }
      console.log(formRows);
      isLoading.value = false;
    } catch (error: any) {}
    isLoading.value = false;
    return false;
  }

  const formRules = reactive<any>({});

  /* 弹窗 保存 事件，仅通知调用组件 */
  const onFinish = async () => {
    try {
      const formValues = await formRef.value.validateFields();
      //console.log("表单校验后的键值对",formValues)

      // 2. 转换为数组格式（与 formRows 结构一致）
      const fields = Object.keys(formValues).map((indexStr) => {
        const index = Number(indexStr); // 动态行索引
        const rowValues = formValues[indexStr]; // 该行的所有字段值
        return {
          ...formRows[index], // 保留原始数据（如 id、field_name 等不可编辑字段）
          ...rowValues, // 覆盖表单编辑后的值
        } as FormRow;
      });
      // 3. 合并参数：getParams（table_config_id） + 表单数组（fields）
      const submitData = {
        table_config_id: getParams.value.table_config_id, // 从查询参数获取
        fields: fields, // 表单数组
      };
      //console.log("合并后提交参数：", submitData);
      const ret = await postFormData(postAction.value, submitData);
      if (ret) {
        onCancel();
      }
      //console.log("返回结果：", ret);
    } catch (error) {
      return;
    }
  };

  const postAction = ref('base.manage.fieldconfig.ServiceImpl.update');

  /* 数据服务请求（访问服务端接口获取数据） */
  async function postFormData(action: string, params: Record<string, any>): Promise<boolean> {
    isLoading.value = true;
    try {
      //await formRef.value.validate();
      try {
        const result = await bizApi.httpSave(action, params);
        isLoading.value = false;
        message.success({
          // content: result.sub_message || '数据保存成功',
          content: '数据保存成功',
        });
        return true;
      } catch (error: any) {
        console.log(error);
        isLoading.value = false;
        return Promise.reject(error);
      }
    } catch (error) {}
    isLoading.value = false;
    return false;
  }

  /* ----------------------- 暴露方法给父组件 ------------------------ */
  defineExpose({
    show,
  });

  /* ----------------------- 拖拽逻辑代码 ----------------------- */
  const modalTitleRef = ref();
  const { x, y, isDragging } = useDraggable(modalTitleRef);

  // 拖拽起始位置
  const startX = ref(0);
  const startY = ref(0);
  const startedDrag = ref(false);

  // 当前变换的坐标
  const transformX = ref(0);
  const transformY = ref(0);

  // 拖拽前的变换坐标
  const preTransformX = ref(0);
  const preTransformY = ref(0);

  // 拖拽区域的边界矩形
  const dragRect = ref({ left: 0, right: 0, top: 0, bottom: 0 });

  // 监听x、y坐标变化，更新拖拽起始位置和边界信息
  watch([x, y], () => {
    if (!startedDrag.value) {
      startX.value = x.value;
      startY.value = y.value;

      const bodyRect = document.body.getBoundingClientRect();
      const titleRect = modalTitleRef.value.getBoundingClientRect();
      dragRect.value.right = bodyRect.width - titleRect.width;
      dragRect.value.bottom = bodyRect.height - titleRect.height;

      preTransformX.value = transformX.value;
      preTransformY.value = transformY.value;
    }
    startedDrag.value = true;
  });
  watch(isDragging, () => {
    if (!isDragging) {
      startedDrag.value = false;
    }
  });

  // 计算拖拽过程中的变换坐标，确保在有效范围内
  watchEffect(() => {
    if (startedDrag.value) {
      transformX.value =
        preTransformX.value + Math.min(Math.max(dragRect.value.left, x.value), dragRect.value.right) - startX.value;
      transformY.value =
        preTransformY.value + Math.min(Math.max(dragRect.value.top, y.value), dragRect.value.bottom) - startY.value;
    }
  });

  // 通过计算样式移动弹窗
  const transformStyle = computed<CSSProperties>(() => {
    return {
      transform: `translate(${transformX.value}px, ${transformY.value}px)`,
    };
  });
</script>
<style lang="less" scoped>
  .modal-content {
    /* 给表单内容加左右内边距，避免贴边 */
    padding: 0 2px;

    .ant-col {
      min-height: 32px;
      line-height: 32px;
    }

    .ant-form-item {
      margin-bottom: 0;
    }

    .form-row {
      padding-bottom: 10px;
      border-bottom: 1px dashed #f0f0f0;

      &:last-child {
        border-bottom: none;
      }
    }
  }

  .modal-footer {
    margin-top: 20px;
    padding: 16px 24px;
    border-top: 1px solid #f0f0f0;
  }

  .form-item-buttons {
    margin-top: auto;
  }

  :deep(.ant-modal-content) {
    padding-top: 0;
  }

  .draggable-modal {
    .title {
      position: sticky;
      top: 0;
      padding-top: 20px;
      width: 100%;
      cursor: move;
    }
  }
</style>
